#include"Dlinklist.h"

void DTLInit(DTL** pphead)
{
	(*pphead) = BuyNewNode(-1);
	(*pphead)->next = *pphead;
	(*pphead)->prev = *pphead;
}
DTL* BuyNewNode(ElemType x)
{
	DTL* newnode = (DTL*)malloc(sizeof(DTL));
	if (newnode == NULL)
	{
		perror("malloc failed");
		exit(-1);
	}
	newnode->data = x;
	newnode->next = NULL;
	newnode->prev = NULL;

	return newnode;
}
void DTLBackPush(DTL* phead, ElemType x)
{
	assert(phead);
	DTL* newnode = BuyNewNode(x);
	DTL* tail = phead->prev;

	tail->next = newnode;
	newnode->next = phead;

	phead->prev = newnode;
	newnode->prev = tail;
}
void DTLFrontPush(DTL* phead, ElemType x)
{
	assert(phead);
	DTL* newnode = BuyNewNode(x);
	DTL* befnext= phead->next;

	phead->next = newnode;
	newnode->prev = newnode;

	newnode->next = befnext;
	befnext->prev = newnode;
	
}
void DTLDestory(DTL** pphead)
{
	DTL* cur = (*pphead)->next;
	while (cur != (*pphead))
	{
		DTL* del = cur;
		cur = cur->next;
		free(del);
	}
	free(*pphead);
	(*pphead)->next = NULL;
	(*pphead)->prev = NULL;
	(*pphead) = NULL;

}
void DTLPrint(DTL* phead)
{
	DTL* cur = phead->next;
	while (cur->next != phead)
	{
		printf("%c <--> ", cur->data);
		cur = cur->next;
	}
	printf("%c   \n ", cur->data);

}
void DTLFrontPop(DTL* phead)
{
	assert(phead);
	DTL* aftnext = phead -> next->next;
	free(phead->next);
	phead->next->next = NULL;
	phead->next->prev = NULL;

	phead->next = aftnext;
	aftnext->prev = phead;
}
void DTLBackPop(DTL* phead)
{
	assert(phead);
	DTL* beftail = phead->prev->prev;
	free(phead->prev);
	phead->prev->next = NULL;
	phead->prev->prev = NULL;

	beftail->next = phead;
	phead->prev = beftail;
}

int DTLSize(DTL* phead)
{
	assert(phead);
	DTL* cur = phead->next;
	int count = 0;
	while (cur != phead)
	{
		count++;
		cur = cur->next;
	}
	return count;
}

bool DTLEmpty(DTL* phead)
{
	assert(phead);
	DTL* next = phead->next;
	return phead == next;
}

DTL* DTLbySub(DTL* phead, ElemType sub)
{
	assert(phead);
	DTL* cur = phead->next;
	while (cur != phead)
	{
		if (sub == 1)
		{
			return cur;
		}
		sub--;
		cur = cur->next;
	}
	return NULL;
}
int DTLbyel(DTL* phead, ElemType x)
{
	assert(phead);
	int count = 1;
	DTL* cur = phead->next;
	while (cur != phead)
	{
		if (cur->data==x)
		{
			return count;
		}
		count++;
		cur = cur->next;
	}
	return -1;
}

void DTLInsertPos(DTL* phead, int el, ElemType x)
{
	assert(phead);
	DTL* cur = DTLbySub(phead, el);
	DTL* befprev = cur->prev;
	DTL* newnode = BuyNewNode(x);
	
	befprev->next = newnode;
	newnode->prev = befprev;

	newnode->next = cur;
	cur->prev = newnode;
}

void DTLPopPos(DTL* phead, int el)
{
	assert(phead);
	DTL* cur = DTLbySub(phead, el);

	DTL* aftnext = cur->next;
	DTL* befprev = cur->prev;

	free(cur);
	cur->next = NULL;
	cur->prev = NULL;

	aftnext->prev = befprev;
	befprev->next = aftnext;
}